package ngat.oss.simulation;

import ngat.phase2.*;
import java.util.*;

public class BasicHistoryModel implements ExecutionHistoryModel {

    /** Stores latest history entries.*/
    Map history;

    /** Stores full history vectors.*/
    Map allHistory;

    /** Create a BasicHistoryModel.*/
    public BasicHistoryModel() {
	history = new HashMap();
	allHistory = new HashMap();
    }

    /** Clear the history map for all groups.*/
    public void clearHistory() { allHistory.clear(); }
    
    /** Convenience method?*/
    public void setHistory(Group group, List ghist) {
	allHistory.put(group.getFullPath(), ghist);
    }

    /** Clear history for a specified group.*/
    public void clearHistory(Group group) {
	if (!allHistory.containsKey(group.getFullPath()))
	    return;

	List ghist = (List)allHistory.get(group.getFullPath());
	if (ghist == null)
	    return; 

	ghist.clear();
    }

 //    /** Add a history entry for the specified group to the history map.*/
//     public void addHistoryItem(Group group, long lastExecuted, int countExecutions) {
// 	history.put(group.getFullPath(), new ExecutionStatistics(lastExecuted, countExecutions));	
//     }
    
    /** Update the history entry for the specified group to supplied latest time.*/
    public void updateHistory(Group group, long lastExecuted) {
	List ghist = (List)allHistory.get(group.getFullPath());
	if (ghist == null) {
	    ghist = new Vector();
	    allHistory.put(group.getFullPath(), ghist);
	    System.err.println("BHM: Create true history entry for: "+group.getName());
	}
	ghist.add(new Long(lastExecuted));
	//System.err.println("BHM: Add true update "+ghist.size()+" for: "+group.getName()+" at "+ScheduleSimulator.sdf.format(new Date(lastExecuted)));
    }
    

  //   /** Returns the last time the specified group was successfully executed or -1 if never.*/
//     public long getLastExecuted(Group group) {
// 	if (! history.containsKey(group.getFullPath()))
// 	    return -1L;
	
// 	return  ((ExecutionStatistics)(history.get(group.getFullPath()))).lastExecuted;
//     }

//     /** Returns the number of times the specified group has been successfully executed.*/
//     public int countExecutions(Group group) {
// 	if (! history.containsKey(group.getFullPath()))
// 	    return 0;
	
// 	return  ((ExecutionStatistics)(history.get(group.getFullPath()))).countExecutions;
//     }


     /** Returns the execution statistics for the specified group at time.*/
    public ExecutionStatistics getExecutionStatistics(Group group, long time) {
	List ghist = (List)allHistory.get(group.getFullPath());
	if (ghist == null)
	    return new ExecutionStatistics(0L, 0); /// TEST
	int count = 0;
	long lastDone = 0L;
	Iterator ih = ghist.iterator();
	while (ih.hasNext()) {
	    Long h = (Long)ih.next();
	    if (h.longValue() < time) {
		count++;
		lastDone = h.longValue();
	    }
	}
	
	return new ExecutionStatistics(lastDone, count);

    }

    /** Returns the execution statistics for the specified group to last recorded time.*/
    public ExecutionStatistics getExecutionStatistics(Group group) {
	List ghist = (List)allHistory.get(group.getFullPath());
	if (ghist == null)
	    return new ExecutionStatistics(0L, 0);/// TEST
	int count = ghist.size();
	long lastDone = 0L;
	if (count == 0)
	    lastDone = 0L;
	else
	    lastDone = ((Long)ghist.get(count-1)).longValue();
	
	return new ExecutionStatistics(lastDone, count);

    }

    /** Load the history from the supplied ODB cache for executions prior to time.*/
    public void loadHistory(Phase2Model phase2, long time) throws Exception {
 
	long st = System.currentTimeMillis();
        int nh = 0;
	
        Iterator ip = phase2.listProposals();
        while (ip.hasNext()) {
	    
            try {

                Proposal proposal = (Proposal)ip.next();
		
                if (proposal == null) continue;
		
                Iterator iGroup = proposal.listAllGroups();

                while (iGroup.hasNext()) {
		    
                    Group group = (Group)iGroup.next();

		    int count = 0;
		    	    
		    Iterator ih = group.getHistory().iterator();
		    while (ih.hasNext()) {
			Group.History h = (Group.History)ih.next();
			if (h.getDate() < time && h.getDone()) {
			    count++;		
			    updateHistory(group, h.getDate());
			}
		    }
		    
		} // next group
		
            } catch (Exception e) {
                e.printStackTrace();
            }
	    
	} // next proposal
	
    }
    
}
